using UnityEngine;

public class HitBallDemo : MonoBehaviour
{
	public HitAnimationsStateEnum hitAnimEnum;

	[Header("Params")]
	[Range(0.02f, 1f)]
	public float crossFadeDuration = 0.05f;

	[Range(0f, 4f)]
	public float timeScale = 1f;

	[Range(-1f, 1f)]
	public float xBall;

	[Range(0f, 1f)]
	public float yBall = 0.5f;

	[Range(-1f, 1f)]
	public float zBall;

	public float desiredSpeed = 4f;

	[Header("Display")]
	public Vector3 realHitPoint;

	public Vector3 calculatedHitPoint;

	public Vector3 movePositionOnFloor;

	[Header("Setup")]
	public Transform ball;

	public Transform start;

	public Transform racketCenter;

	private Vector3 prevRacketCenter;

	private float prevTime;

	protected KineticPlan kineticPlan
	{
		get
		{
			return GetComponent<KineticPlan>();
		}
	}

	public HitAnimationInfo hitAnim
	{
		get
		{
			return ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(hitAnimEnum);
		}
	}

	public void UpdateBallPos()
	{
		FloatRange floatRange = default(FloatRange);
		floatRange.min = 0f - Table.halfwidth;
		floatRange.max = Table.halfwidth;
		FloatRange floatRange2 = floatRange;
		floatRange = default(FloatRange);
		floatRange.min = Table.tabletopy;
		floatRange.max = Table.tabletopy + 5f * Table.netHeight;
		FloatRange floatRange3 = floatRange;
		floatRange = default(FloatRange);
		floatRange.min = (0f - Table.halfLength) * 0.5f;
		floatRange.max = Table.halfLength * 0.5f;
		FloatRange floatRange4 = floatRange;
		Vector3 position = Vector3.up * floatRange3.Lerp(yBall) + Vector3.right * floatRange2.LerpMinMax(xBall) + Vector3.back * (Table.halfLength + floatRange4.LerpMinMax(zBall));
		ball.position = position;
	}

	public void HitBall()
	{
		HitAnimationInfo hitAnimationInfo = hitAnim;
		Vector3 vector = (ball.position - hitAnimationInfo.hitPosition).OnGround();
		KineticPlan.AnimSearchSolution animSearchSolution = FindSolutionToPosition(vector);
		bool flag = true;
		Vector3 startPosition = animSearchSolution.startPosition;
		Quaternion startRotation = animSearchSolution.startRotation;
		float num = animSearchSolution.totalDuration + hitAnimationInfo.hitTime;
		float num2 = animSearchSolution.desiredPositionChange.magnitude / num;
		float num3 = desiredSpeed / num2;
		foreach (MoveAnimationInfo anim in animSearchSolution.animList)
		{
			KineticElementMove kineticElementMove = new KineticElementMove();
			kineticElementMove.animInfo = anim;
			if (flag)
			{
				kineticElementMove.startPosition = animSearchSolution.startPosition;
				kineticElementMove.startRotation = animSearchSolution.startRotation;
				flag = false;
			}
			else
			{
				kineticElementMove.startFromCurrentPosition = true;
			}
			kineticElementMove.crossFadeDuration = crossFadeDuration;
			Vector3 a = startPosition;
			Debug.Log(string.Concat("Anim ", anim.animatorStateName, " Adjust vector ", anim.GetAdjustVector(animSearchSolution.xAdjust, animSearchSolution.zAdjust), " desired change ", animSearchSolution.desiredPositionChange));
			startPosition += startRotation * (anim.positionChange + anim.GetAdjustVector(animSearchSolution.xAdjust, animSearchSolution.zAdjust));
			startRotation *= anim.rotationChange;
			float num4 = Vector3.Distance(a, startPosition) / anim.clipLength;
			kineticElementMove.useDesiredEnd = true;
			kineticElementMove.desiredEndPosition = startPosition;
			kineticElementMove.animatorSpeed = desiredSpeed / num4;
			kineticPlan.AddElement(kineticElementMove);
		}
		float num5 = Vector3.Distance(vector, startPosition) / hitAnimationInfo.hitTime;
		movePositionOnFloor = startPosition;
		KineticElementHit kineticElementHit = new KineticElementHit();
		kineticElementHit.animInfo = hitAnimationInfo;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticElementHit.hitPosition = ball.position + hitAnimationInfo.racketRotationAtHit * (Vector3.back * ball.localScale.z * 0.5f);
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.desiredEndPosition = vector;
		kineticElementHit.useDesiredEnd = true;
		kineticElementHit.animatorSpeed = desiredSpeed / num5;
		kineticPlan.AddElement(kineticElementHit);
	}

	private KineticPlan.AnimSearchSolution FindSolutionToPosition(Vector3 position)
	{
		KineticPlan.SearchParams searchParams = default(KineticPlan.SearchParams);
		searchParams.startPos = start.position;
		searchParams.startRot = start.rotation;
		searchParams.endPos = position;
		searchParams.maxDepth = 5;
		KineticPlan.SearchParams p = searchParams;
		p.hitAnimation = hitAnim;
		return kineticPlan.FindPathToGetToPosition(p);
	}

	private void Update()
	{
		Time.timeScale = timeScale;
	}

	private void LateUpdate()
	{
		KineticElementHit kineticElementHit = kineticPlan.activeElement as KineticElementHit;
		if (kineticElementHit != null && kineticElementHit.isActive && Time.timeScale != 0f)
		{
			Animator component = GetComponent<Animator>();
			float num = component.GetCurrentAnimatorStateInfo(0).normalizedTime * kineticElementHit.hitInfo.clipLength;
			if (prevTime <= kineticElementHit.hitInfo.hitTime && num >= kineticElementHit.hitInfo.hitTime && !component.IsInTransition(0))
			{
				realHitPoint = Vector3.Lerp(prevRacketCenter, racketCenter.position, (kineticElementHit.hitInfo.hitTime - (num - Time.deltaTime)) / Time.deltaTime);
				Vector3 vector = kineticElementHit.startPosition + kineticElementHit.startRotation * kineticElementHit.hitInfo.hitPosition;
				Vector3 vector2 = kineticElementHit.hitPosition - vector;
				calculatedHitPoint = kineticElementHit.startPosition + kineticElementHit.startRotation * kineticElementHit.hitInfo.hitPosition + vector2;
			}
			prevRacketCenter = racketCenter.position;
			prevTime = num;
		}
	}
}
